#!/usr/bin/env bash

# params: [printf_if=-] [suffix]
__rvm_system_path()
{
  rvm_remote_server_path="$(__rvm_db "rvm_remote_server_path${2:-}")"
  [[ -n "${rvm_remote_server_path}" ]] ||
  rvm_remote_server_path="${_system_name_lowercase}/${_system_version}/${_system_arch}"
  if [[ "${1:-}" == "-" ]]
  then printf "%b" "${rvm_remote_server_path}\n"
  fi
}

__rvm_remote_extension()
{
  case "$1" in
    *.tar.*)
      rvm_remote_extension="tar${1##*tar}"
      ;;
    jruby-*)
      rvm_remote_extension="tar.gz"
      ;;
    *)
      rvm_remote_extension="tar.bz2"
      ;;
  esac
  [[ "$2" != "-" ]] || printf "%b" "${rvm_remote_extension}"
}

# params: ruby-string-to-transform
__rvm_ruby_package_file()
{
  case "$1" in
    *.tar.*)
      rvm_ruby_package_file="/$1"
      ;;
    rbx*|rubinius*)
      rvm_ruby_package_file="/${1//rbx/rubinius}.$(__rvm_remote_extension "$1" -)"
      ;;
    jruby-head)
      rvm_ruby_package_file="/jruby-head.$(__rvm_remote_extension "$1" -)"
      ;;
    jruby*)
      \typeset __version
      __version="$(
        rvm_ruby_string="$1"
        rvm_remote_flag=0 __rvm_ruby_string
        echo "$rvm_ruby_version"
      )"
      rvm_ruby_package_file="/${__version}/jruby-dist-${__version}-bin.$(__rvm_remote_extension "$1" -)"
      ;;
    "")
      rvm_ruby_package_file=""
      ;;
    ruby*|mruby*)
      rvm_ruby_package_file="/$1.$(__rvm_remote_extension "$1" -)"
      ;;
    *)
      rvm_ruby_package_file="/ruby-$1.$(__rvm_remote_extension "$1" -)"
      ;;
  esac
}

__rvm_include_travis_binaries()
{
  if [[ $rvm_remote_server_url == *"travis"* && $TRAVIS != true && $_system_name_lowercase == "osx" ]]
  then
      rvm_debug "Travis binaries for OSX are not movable and can't be used outside of Travis environment. \
Skip that source."
      return 1
  fi

  return 0
}

__rvm_calculate_remote_file()
{
  rvm_remote_server_url="$( __rvm_db "rvm_remote_server_url${3:-}" )"

  [[ -n "$rvm_remote_server_url" ]] || {
    rvm_debug "rvm_remote_server_url${3:-} not found"
    return $1
  }

  __rvm_include_travis_binaries || return $1

  __rvm_system_path "" "${3:-}"
  __rvm_ruby_package_file "${4:-}"
  __remote_file="${rvm_remote_server_url}/${rvm_remote_server_path}${rvm_ruby_package_file}"
}

# params: return_on_end return_on_failed_link [suffix] [file]
__rvm_remote_server_path_single()
{
  \typeset __remote_file
  __rvm_calculate_remote_file "$@" || return $?
  if
    [[ -z "${__remote_file:-}" ]]
  then
    rvm_debug "No remote file name found"
    return $1
  elif
    file_exists_at_url "${__remote_file}"
  then
    rvm_debug "Remote file exists ${__remote_file}"
    printf "%b" "$( __rvm_db "rvm_remote_server_verify_downloads${3:-}" ):${__remote_file}"
  elif
    [[ -f "${rvm_archives_path}/${rvm_ruby_package_file##*/}" && "${rvm_ruby_package_file##*/}" == *bin-* ]]
  then
    rvm_debug "Cached file exists ${__remote_file}"
    printf "%b" "$( __rvm_db "rvm_remote_server_verify_downloads${3:-}" ):${rvm_archives_path}/${rvm_ruby_package_file##*/}"
  else
    rvm_debug "Remote file does not exist ${__remote_file}"
    return $2
  fi
}

# params: [file_name]
__rvm_remote_server_path()
{
  \typeset _iterator
  _iterator=""
  while ! __rvm_remote_server_path_single 0 1 "${_iterator}" "${1:-}"
  do : $(( _iterator+=1 ))
  done
}

__list_remote_all()
{
  \typeset _iterator rvm_remote_server_url rvm_remote_server_path
  _iterator=""

  while
    __rvm_db "rvm_remote_server_url${_iterator:-}" rvm_remote_server_url
  do
    if
      __rvm_include_travis_binaries
    then
      __rvm_system_path "" "${_iterator}"
      rvm_debug "__list_remote_all${_iterator:-} $rvm_remote_server_url $rvm_remote_server_path"

      __list_remote_for "${rvm_remote_server_url}" "$rvm_remote_server_path"
    fi
    : $(( _iterator+=1 ))
  done | \command \sort -u | __rvm_version_sort
}

__list_remote_for()
{
  __list_remote_for_local "$@" ||
  __list_remote_for_index "$@" ||
  __list_remote_for_s3    "$@" ||
  return $?
}

__list_remote_for_local()
{
  \typeset __status1 __status2
  __status1=0
  __status2=0
  if [[ -f $rvm_user_path/remote ]]
  then __rvm_grep "${1}/${2}" < $rvm_user_path/remote || __status1=$?
  fi
  __rvm_grep "${1}/${2}" < $rvm_path/config/remote || __status2=$?
  if (( __status1 || __status2 ))
  then return 1
  else rvm_debug "__list_remote_for_local found"
  fi
  true # for OSX
}

__list_remote_for_index()
{
  if
    file_exists_at_url "${1}/index.txt"
  then
    rvm_debug "__list_remote_for_index ${1}/index.txt"
    __rvm_curl -s "${1}/index.txt" | GREP_OPTIONS="" \command \grep -E "${1}/${2}/.*\.tar\.(gz|bz2)$"
  elif
    file_exists_at_url "${1}/${2}/index.txt"
  then
    rvm_debug "__list_remote_for_index ${1}/${2}/index.txt"
    __rvm_curl -s "${1}/${2}/index.txt" | GREP_OPTIONS="" \command \grep -E "${1}/${2}/.*\.tar\.(gz|bz2)$"
  else
    return 1
  fi
  true # for OSX
}

__list_remote_for_s3()
{
  curl -ILfs "${1}" | __rvm_grep "Server: AmazonS3" >/dev/null || return $?
  \typeset __tmp_name __iterator __next __local_url
  __iterator=0
  __next=""
  __tmp_name="$(
    : ${TMPDIR:=${rvm_tmp_path:-/tmp}}
    mktemp "${TMPDIR}/tmp.XXXXXXXXXXXXXXXXXX"
  )"
  while
    [[ __iterator -eq 0 || -n "${__next}" ]]
  do
    __local_url="${1}?prefix=${2}/${__next:+&marker=${__next}}"
    rvm_debug "__list_remote_for_s3-${__iterator} ${__local_url}"
    __rvm_curl -s "${__local_url}" > "${__tmp_name}${__iterator}"

    GREP_OPTIONS="" \command \grep -oE "<Key>[^<]*</Key>" < "${__tmp_name}${__iterator}" |
    __rvm_awk -F"[<>]" '{print $3}' > "${__tmp_name}"

    if __rvm_grep "<IsTruncated>true</IsTruncated>" < "${__tmp_name}${__iterator}"
    then __next="$(__rvm_tail -n 1 "${__tmp_name}")"
    else __next=""
    fi

    rm "${__tmp_name}${__iterator}"
    : $(( __iterator+=1 ))
  done
  GREP_OPTIONS="" \command \grep -E "${2}/.*\.tar\.(gz|bz2)$" < "${__tmp_name}" |
  GREP_OPTIONS="" \command \grep -v -- "-src-" |
  __rvm_awk "{ print "'"'$1/'"'"\$1 }"
  rm "${__tmp_name}"*
}

__rvm_get_user_shell()
{
  case "${_system_type}:${_system_name}" in
    (Windows:Mingw|Linux:Termux)
      __shell="$( echo $SHELL )" ||
      {
        rvm_error "Error checking user shell from echo \$SHELL ... something went wrong, report a bug."
        return 2
      }
      echo "${__shell##*:}"
      ;;

    (Linux:*|SunOS:*|BSD:*|Windows:Cygwin)
      __shell="$( getent passwd $USER )" ||
      {
        rvm_error "Error checking user shell via getent ... something went wrong, report a bug."
        return 2
      }
      echo "${__shell##*:}"
      ;;

    (Darwin:*)
      \typeset __version

      __version="$(dscl localhost -read "/Search/Users/$USER" UserShell)" ||
      {
        rvm_error "Error checking user shell via dscl ... something went wrong, report a bug."
        return 3
      }
      echo ${__version#*: }
      ;;

    (*)
      rvm_error "Do not know how to check user shell on '$(command uname)'."
      return 1
      ;;
  esac
}
